class User < ActiveRecord::Base
  has_many :bets
  has_many :user_actions
  has_many :got_challenges,:class_name=>"Challenge",:foreign_key=>:to_user_id,:conditions=>["mode = ?","bet_0"],:order=>'id desc'
  has_many :sent_challenges,:class_name=>"Challenge",:foreign_key=>:from_user_id,:conditions=>["mode =?","bet_0"],:order=>'id desc'
  has_many :point_histories
  has_many :matches,:through=>:bets,:source=>:match do 
    def next
      proxy_owner.matches.played(false).first(:order=>"begin_at asc ,id asc")
    end
  end
  after_create :add_init_point

  def add_init_point
    self.point = PointConfig.find_by_name("user_start").point
    self.save
    if ph = PointHistory.find(:first,:conditions=>["action='invite friend' and related_user_id=?",self.id])
      u = User.find(ph.user_id)
      u.point = u.point + PointConfig.find_by_name("invite_received").point
      u.invitation_accept_number = u.invitation_accept_number.to_i + 1
      u.save
    end
  end
  
  def other_friends(sid)
     other_ids = (self.all_friends.split(",") - joined_ids = Match.find(sid).bets.map{|b| b.user_id}).join(",") 
     User.find(:all,:conditions=>"id in (#{other_ids})")
  end
  #get bet through match
  def bet(match)
    Bet.find(:first,:conditions=>["user_id = ? and match_id = ?",self.id,match.id])
  end



  def challenge_status(to_user,sid)
    ch = Challenge.find(:first,:conditions=>["match_id = ? and from_user_id = ? and to_user_id = ? ",sid,self.id,to_user.id])  
    ch2 = Challenge.find(:first,:conditions=>["match_id = ? and to_user_id = ? and from_user_id = ?",sid,self.id,to_user.id])  
    res = {:ch=>nil,:status=>nil}

    if ch 
      res[:ch]=ch
      if ch.mode == "bet_0"
	res[:status] = "ch_sent"
      else
	res[:status] = "ch_accept"
      end
        res[:status] = "ch_expired" if ch.match.begin_at < Time.now 
      return res
    elsif ch2
      res[:ch]=ch2
      if ch2.mode == "bet_0"
	res[:status] = "ch_wait_accept"
      else
	res[:status] = "ch_was_accept"
      end
        res[:status] = "ch_expired" if ch2.match.begin_at < Time.now 
    else
      if Match.find(sid).begin_at < Time.now
	res[:status] = "ch_expired"
      else
	res[:status] = "place_ch_link"
      end
    end

    return res
  end
  
  def add_point(p)
      self.point = self.point.to_i + p
      self.save
  end
  def bought_win?
     BuyWin.find(:first,:conditions=>["user_id=? and point_config_id=0 and winstreak_id=?",self.id,self.winstreak.id])
  end
  def bought_wins
     BuyWin.find(:all,:conditions=>["user_id=? and point_config_id>0 and winstreak_id=?",self.id,self.winstreak.id])
  end

  has_many :winstreaks do
    def next_position
      max_position_winstreak = first :order=>"position desc"
      max_position_winstreak.nil? ? 0 : max_position_winstreak.position + 1
    end
  end
  belongs_to :winstreak # current winstreak
  belongs_to :prize

  named_scope :rank,:order=>"#{Winstreak.table_name}.streak_count desc",:include=>[:winstreak]
  # ensure winstreak exists.
  def winstreak_with_ensure_exists
    winstreak_without_ensure_exists || reset_winstreak
  end

  def prize_with_ensure_selected
    prize_without_ensure_selected ||  auto_assign_prize
  end

  alias_method_chain :winstreak,:ensure_exists
  alias_method_chain :prize,:ensure_selected

  def auto_assign_prize
    self.prize = Prize.first
    self.save
    prize
  end

  # if winstreak is not exists.
  # then create one 

  # administrators
  def admin?
    # aotianlong
    [752103199,523941085,5408990,826873].include?(facebook_id)
  end

  # this should cached
  def best_winstreak
    @best_winstreak ||= winstreaks.first(:order=>"streak_count desc,id desc")
  end

  # 用户当前的连胜次数
  def current_winstreak_count
    #winstreak.nil? ? 0 : winstreak.streak_count 
    # add buy win times to current_count
    winstreak.nil? ? 0 : winstreak.streak_count
  end

  # 更改奖品
  # 只有winstreak为空的时候才可以更改？
  def change_prize(prize)
    if winstreak.nil? || winstreak.streak_count.to_i.zero?
      self.prize = prize
      reset_winstreak if winstreak.nil?
      winstreak.prize = prize
      winstreak.save
      save
    else
      false
    end
  end

  def friends
    User.scoped(:conditions=>["#{User.table_name}.id in (?)",friend_ids])
  end

  def friend_ids
    @friend_ids ||= Facebooker::Session.current.user.friends.collect(&:facebook_id)
  end

  # 重置连胜记录
  def reset_winstreak
    new_winstreak = winstreaks.build(:prize=>prize)
    new_winstreak.position = winstreaks.next_position
    new_winstreak.save
    self.winstreak = new_winstreak
    # here should re calculate the best previrous winstreak
    save(false)
    new_winstreak
  end

  # 离获取奖品还需要多少次连胜
  # 如果连奖品都没有选，或者一次都没有下注，那么返回nil
  # 否则会返回对应奖品的连胜次数
  def streak_remain
    winstreak && winstreak.streak_remain   if prize
  end

  def facebook_user
    @facebook_user ||= Facebooker::User.new id
  end

  def calc_percentage
    self.wins_count = bets.played(true).win(true).count + self.bought_wins.size
    self.losses_count = bets.played(true).win(false).count
    if wins_count.zero? && losses_count.zero?
      self.win_percentage = 100.0
    else
      self.win_percentage = ((wins_count/(wins_count + losses_count).to_f)*100).ceil
    end
    save
    self.win_percentage
  end

  def self.for(facebook_session)
    return if facebook_session.nil?
    uid = facebook_session.user.facebook_id
    user = User.find_or_initialize_by_id(uid)
    if user.new_record?
      # initialize other attributes here
      facebook_user = facebook_session.user
      user.name = facebook_user.name
      user.sex = facebook_user.sex
      user.birthday = facebook_user.birthday
      if user.birthday
        user.age = Time.now.year - user.birthday.year
      end
      user.country = facebook_user.hometown_location
      user.facebook_id = uid
      user.profile_updated_at = facebook_user.profile_update_time
      user.app_user = facebook_user.is_app_user
      user.save!
    end
    user
  end

  def current_streak_bets
    bets = self.bets.played(false).all :include=>{:match=>[:home_team,:away_team]},
      :order=>"#{Match.table_name}.begin_at ASC"
    current_bets = winstreak && winstreak.bets(:include=>[:match],:order=>"#{Match.table_name}.begin_at ASC")
    current_bets ||= []
    current_bets + bets
  end

  def current_streak_bets_count
  end

  
  def last_lose_bet
    bets.first :conditions=>{:played=>true,:win=>false},
      :order=>"#{Match.table_name}.begin_at DESC",
      :include=>:match
  end

  # all actions will be sent
  # only sent latest feed
  def publish_delayed_actions
    WinstreakPublisher # auto load this class, let user_action.feed find this class
    user_action = user_actions.first :order=>"created_at DESC"
    if user_action
      user_action.feed.send_delayed_message
      # destroy all
      user_actions.destroy_all
    end
  end

  alias_method :publish_delayed_action,:publish_delayed_actions

end
